package com.zhouheng.springbootdesignpattern.proxypattern.jdkdynamicproxy;

import java.lang.reflect.Proxy;

/**
 * 创建JDK，动态代理对象
 * 动态代理不需要实现接口，但是需要指定接口类型
 *
 * @author 周恒
 * @date 20190610 16:45:01
 * @since v1.0
 */
public class ProxyFactory {

    /**
     * target 维护一个目标对象
     */
    private Object target;

    public ProxyFactory(Object target) {
        this.target = target;
    }

    /**
     * 获取代理实例
     * JDK实现代理只需要使用Proxy.newProxyInstance方法
     * 三个参数
     * 一、ClassLoader loader,:指定当前目标对象使用类加载器,获取加载器的方法是固定的
     * 二、Class<?>[] interfaces,:目标对象实现的接口的类型,使用泛型方式确认类型
     * 三、InvocationHandler h:事件处理,执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入
     * lambda表达式的方式实现InvocationHandler
     * method.invoke(target, args，...)，...匹配参数类型，没匹配到会报错
     *
     * @return 返回 object 描述此返回参数
     * @author 周恒
     * @date 20190610 16:44:41
     * @since v1.0
     */
    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
                target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    System.out.println("开始事务2");
                    //执行目标方法（args：代理传进来的参数）
                    Object returnValue = method.invoke(target, args);
                    System.out.println("提交事务2");
                    return returnValue;
                }
                /*new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("开始事务2");
                        //执行目标方法
                        Object returnValue = method.invoke(target, args);
                        System.out.println("提交事务2");
                        return returnValue;
                    }
                }*/
        );
    }

}
